package parserjc.jaccie;

import java.util.*;

/**
 * @author Ralf Meyer,
 * "Erstellung von Compiler Compiler Komponenten f�r die Zielsprache Java"
 * UniBwM - ID26/96
 *
 * The following methods are implemented by Volker Seibt:
 * expand
 */

public final class SICStack extends Object {

    protected Stack stack = new Stack();

    public SICStack() {}

    public void push( int state,SICTree element ) {
        Vector stackElement = new Vector(2);
        stackElement.addElement(new Integer(state));
        element.setState(state);
        stackElement.addElement(element);
        stack.push(stackElement);
    }

    public boolean isEmpty() {
        return stack.isEmpty();
    }

    public Vector pop() {
        return (Vector)stack.pop();
    }

    public Vector peek() {
        return (Vector) stack.peek();
    }

    public int peekState() {
        return ((Integer)peek().elementAt(0)).intValue();
    }

    public SICTree peekTree() {
        return (SICTree)peek().elementAt(1);
    }

    public SICTree reduce( int state,String[] rule ) {
        SICTree node = SICTree.newNode(rule[0]);

        for (int i = 0; i<rule.length-1; i++) {
            node.addSonLeft(peekTree());
            state = peekState();
            stack.pop();
        }

        push(state,node);
        return node;
    }

    /**
     * Expands the top stack-element to the given rule's
     * right side.
     */
    public Vector expand(String[] rule) {
        Vector v = new Vector();
        v.addElement(this.pop().elementAt(1));
        for (int i=rule.length-1; i > 0; i--) {
            SICTree st = SICTree.newLeaf(rule[i],null);
            v.insertElementAt(st,1);
            this.push(-1,st);
        }
        return v;
    }


    public void clear() {
        this.stack.removeAllElements();
    }

    public String[] getStringEntries() {
        String[] entries = new String[stack.size()];
        int i = 0;
        Enumeration elements = stack.elements();
        while (elements.hasMoreElements())
            entries[i++] = ((SICTree)((Vector)elements.nextElement()).elementAt(1)).getValue();
        return entries;

    }

    public String toString() {
       String cr = System.getProperties().getProperty("line.separator");
       Stack helpStack = new Stack();
       StringBuffer help = new StringBuffer();

       Vector element;

       while (stack.empty()==false) {
         element = (Vector)stack.pop(); helpStack.push(element);
         help.append(element.elementAt(0));
         help.append(":" + cr);
         help.append(((SICTree)element.elementAt(1)).toString(true,false));
         if (stack.empty()==false) help.append("--------------------" + cr);
       }

       while (helpStack.empty()==false) stack.push(helpStack.pop());
       return help.toString();
    }

    public Vector getTrees() {
        Vector trees = new Vector(stack.size());
        for (int i=0; i < stack.size(); i++)
            trees.addElement(((Vector)stack.elementAt(i)).lastElement());
        return trees;
    }



}
